home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d20
/
doorskl3.arc
/
SAMPLE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-15
|
12KB
|
345 lines
/*
*
* Sample door created with DOORSKEL.LZH archive
*
*/
#include "doorskel.h"
static void _fastcall calendar (void);
static int _fastcall dayno(int yyyy, int mm, int x, int y);
static void _fastcall prt3mon(int yr, int a, char *prtmon);
int _fastcall print_amonth (int yr, int month);
static void _fastcall moontxt (void);
void _fastcall mainloop (void) {
static char *options[] = {"Calendar","Moon Phase","Quit"};
#define NUMSELECTS 3
static char *prompt = "\r\nChoose: ";
int com;
cls();
for(;;) {
carrchk();
getxbbstime();
if(!graphics) {
com = select_one(options,NUMSELECTS,prompt,1);
}
else {
printm("\x1b[s\x1b[2;1H\x1b[K\x1b[u");
com = top_menu(options,NUMSELECTS);
}
switch(com) {
case -1: break;
case 0: calendar();
break;
case 1: moontxt();
break;
case NUMSELECTS - 1: /* quit */
return;
break;
default: printm("\r\nNot yet implemented.\r\n");
break;
}
}
}
/*********************************************************************/
/* */
/* This Program Written by Paul Edwards. */
/* */
/* (Modified very slightly to work as a door by M. Kimes) */
/* This module would replace DOORSKL4.C to create a working door. */
/* */
/* The following block of notes are Paul's. */
/* */
/*********************************************************************/
/*********************************************************************/
/* */
/* Calendar - produce a calendar for any given year. */
/* */
/* This program takes as a command line parameter a single number */
/* which should be a 4 digit year. It then prints out a calendar */
/* corresponding to that year. This program was inspired by a */
/* shareware program which performed a similar function but didn't */
/* come with source! */
/* */
/* Many many thanks to Paul Schlyter, Stockholm, Sweden for his */
/* absolutely fantastically brilliant dow macro. However, due to */
/* limitations of this macro (which are affected by anomolies of */
/* the '/' and '%' operators on negative numbers) this program will */
/* generate invalid calendars for years such as 4 AD. But I reckon */
/* anyone who wants to print out the gregorian calendar for 4 AD is */
/* a total wanker, especially when you consider the fact that the */
/* gregorian calendar only came into existence in 1582. There is */
/* no upper limit to the year the calendar can print. The program */
/* also knows all the rules, ie the 4, 100, 400 year rules for a */
/* leapyear, so that even if you don't know that 1900 wasn't a */
/* leapyear, yet 2000 will be, this program knows! Oh yeah, I'm */
/* not sure exactly where the lower bound on calendars is, but it */
/* will certainly work for anything above 1582. Have fun! Paul. */
/* */
/* This program is dedicated to the public domain. */
/* */
/* Written 1990/8/28. */
/* */
/*********************************************************************/
static void _fastcall calendar (void) {
int yr, wrkyr, dig1, dig2, dig3, dig4;
char yrstr[32];
printm("\r\nYear for calendar? ");
strcpy(yrstr,genin(5,0,0,0,NUM));
printm("\r\n");
if(!*yrstr) return;
yr = atoi(yrstr);
wrkyr = yr;
dig1 = wrkyr / 1000;
wrkyr %= 1000;
dig2 = wrkyr / 100;
wrkyr %= 100;
dig3 = wrkyr / 10;
wrkyr %= 10;
dig4 = wrkyr;
printfm("\r\n %d %d %d %d\r\n\r\n",
dig1,dig2,dig3,dig4);
prt3mon(yr, 0, " JANUARY FEBRUARY"
" MARCH");
prt3mon(yr, 1, " APRIL MAY"
" JUNE");
prt3mon(yr, 2, " JULY AUGUST"
" SEPTEMBER");
prt3mon(yr, 3, " OCTOBER NOVEMBER"
" DECEMBER");
}
static void _fastcall prt3mon (int yr, int a, char *prtmon) {
/* print 3 months */
static char *letters = " s m t w t f s "
" s m t w t f s "
" s m t w t f s\r\n";
int b, i, j, x;
printfm("%s\r\n\r\n",prtmon);
printfm("%s",letters);
for(i = 0;i < 6;i++) {
for(b = 1;b <= 3;b++) {
for(j = 0;j < 7;j++) {
x = dayno(yr,a * 3 + b,i,j);
if(x) printfm("%2d ",x);
else printfm(" ");
}
printfm(" ");
}
printfm("\r\n");
}
return;
}
int _fastcall print_amonth (int yr, int month) {
/* print an individual month...not used in this module... */
int wrkyr, dig1, dig2, dig3, dig4;
char *mons[] = {"JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG",
"SEP","OCT","NOV","DEC"};
char *letters = " s m t w t f s\r\n";
int i, j, x;
wrkyr = yr;
dig1 = wrkyr / 1000;
wrkyr %= 1000;
dig2 = wrkyr / 100;
wrkyr %= 100;
dig3 = wrkyr / 10;
wrkyr %= 10;
dig4 = wrkyr;
printfm("\r\n %d %d %d %d\r\n\r\n",
dig1,dig2,dig3,dig4);
printfm(" %s\r\n",mons[month-1]);
printfm("%s",letters);
for(i = 0;i < 6;i++) {
for(j = 0;j < 7;j++) {
x = dayno(yr,month,i,j);
if (x) printfm("%2d ",x);
else printfm(" ");
}
printfm("\r\n");
}
printfm("\r\n");
return 0;
}
#define isleap(year) ((((year % 4) == 0) && ((year % 100) != 0)) || \
((year % 400) == 0))
#define dow(y,m,d) \
( ( ( 3 * (y) - (7 * ((y) + ((m) + 9) / 12)) / 4 + (23 * (m)) / 9 + (d) + 2 \
+ (((y) - ((m) < 3)) / 100 + 1) * 3 / 4 - 15 ) % 7 ) )
static int daytab[] = { 31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31};
static int _fastcall dayno (int yyyy, int mm, int x, int y) {
int a, b, c;
a = dow(yyyy,mm,1);
b = x * 7 + y;
c = daytab[mm - 1];
if ((mm == 2) && isleap(yyyy)) c++;
if (b < a) return (0);
if ((b - a) >= c) return (0);
return ((b - a + 1));
}
/* =-=-=-=-=-From BSD Unix with modification by Lynn Nash-=-=-=-=-=-=
further hacked by M. Kimes to work in a door
the following block of notes are Lynn's (or from BSD):
* Output the phase of the moon for the given year, month, day.
* The routine calculates the year's epact (the age of the moon on
* Jan 1.), adds this to the number of days in the year, and
* calculates the phase of the moon for this date.
* In the algorithm:
* diy Is the day of the year - 1 (i.e., Jan 1 is day 0).
* golden Is the number of the year in the Mentonic cycle, used to
* determine the position of the calender moon.
* epact Is the age of the calender moon (in days) at the beginning
* of the year. To calculate epact, two century-based
* corrections are applied:
* Gregorian: (3 * cent)/4 - 12
* is the number of years such as 1700, 1800 when
* leap year was not held.
* Clavian: (((8 * cent) + 5) / 25) - 5
* is a correction to the Mentonic cycle of about
* 8 days evry 2500 years. Note that this will
* overflow 16 bits in the year 409600. Beware.
* The algorithm is accurate for the Gregorian calender only.
* The magic numbers used in the phase calculation are as follows:
* 29.5 The moon's period in days.
* 177 29.5 scaled by 6
* 22 (29.5 / 8) scaled by 6 (this gets the phase)
* 11 ((29.5 / 8) / 2) scaled by 6
* Theoretically, this should yield a number in the range 0 .. 7.
* However, two days per year, things don't work out too well.
* Epact is calculated by the algorithm given in Knuth vol. 1
* (calculation of Easter). See also the article on Calenders in
* the Encyclopaedia Britannica and Knuth's algorithm in CACM April
* 1962, page 209.
*/
static char *phasetxt[] = {
"new", /* totally dark */
"waxing crescent", /* increasing to full & quarter light */
"first quarter", /* increasing to full & half light */
"waxing gibbous", /* increasing to full & > than half */
"full", /* fully lighted */
"waning gibbous", /* decreasing from full & > than half */
"last quarter", /* decreasing from full & half light */
"waning crescent" /* decreasing from full & quarter light */
};
static int day_year[] = { /* Days in year for each month */
-1, -1, 30, 58, 89, 119, 150, 180, 211, 241, 272, 303, 333
}; /* Note: Jan. 1 will equal zero */
static void _fastcall moontxt (void) {
int year; /* 1978 = 1978 */
int month; /* Jan = 1 */
int day; /* 1 = 1 */
int phase; /* Moon phase */
int cent; /* Century number (1979 = 20) */
int epact; /* Age of the moon on Jan. 1 */
int diy; /* Day in the year */
int golden; /* Moon's golden number */
char yrstr[32],was;
int c;
printm("\r\nDate for moon phase? ");
strcpy(yrstr,genin(8,0,0,0,DATE));
printm("\r\n");
if(strlen(yrstr) < 8) {
Invalid:
printm("Invalid date.\r\n");
return;
}
was = yrstr[4];
yrstr[4] = 0;
year = atoi(yrstr);
yrstr[4] = was;
was = yrstr[6];
yrstr[6] = 0;
month = atoi(&yrstr[4]);
yrstr[6] = was;
day = atoi(&yrstr[6]);
if (month < 1 || month > 12) goto Invalid;
c = daytab[month - 1];
if ((month == 2) && isleap(year)) c++;
if(day < 1 || day > c) goto Invalid;
diy = day + day_year[month]; /* Day in the year */
if (month > 2 && isleap(year))
diy++; /* Leapyear fixup */
cent = (year / 100) + 1; /* Century number */
golden = (year % 19) + 1; /* Golden number */
epact = ((11 * golden) + 20 /* Golden number */
+ (((8 * cent) + 5) / 25) - 5 /* 400 year cycle */
- (((3 * cent) / 4) - 12)) % 30; /* Leap year correction */
if (epact <= 0)
epact += 30; /* Age range is 1 .. 30 */
if ((epact == 25 && golden > 11) || epact == 24)
epact++;
/*
* Calculate the phase, using the magic numbers defined above.
* Note that (phase and 7) is equivalent to (phase mod 8) and
* is needed on two days per year (when the algorithm yields 8).
*/
phase = (((((diy + epact) * 6) + 11) % 177) / 22) & 7;
printfm("\r\nPhase of the moon: %s\r\n",phasetxt[phase]);
}